home *** CD-ROM | disk | FTP | other *** search
/ FishMarket 1.0 / FishMarket v1.0.iso / fishies / 551-575 / disk_551 / toolmanager / source / dockwindow.c < prev    next >
C/C++ Source or Header  |  1992-05-06  |  12KB  |  509 lines

  1. /*
  2.  * dockwindow.c   V1.5
  3.  *
  4.  * dock window
  5.  *
  6.  * (c) 1991 by Stefan Becker
  7.  *
  8.  */
  9. #include "ToolManager.h"
  10.  
  11. /* Structures for window */
  12. static struct Window *w;
  13. static struct AppWindow *aw;
  14. static struct MsgPort *wp;
  15. static struct RastPort *rp;
  16. static struct Screen *pubsc; /* Workbench screen */
  17. static void *vi;             /* Visual information is a *PRIVATE* data field! */
  18. static WORD ww,wh;
  19. UWORD DockXPos=0,DockYPos=0;
  20. UWORD DockXSize=51,DockYSize=51;
  21. UWORD XOff,YOff;
  22. BOOL DockVertical=TRUE;
  23. BOOL DockToBack=TRUE;
  24. static BOOL DoDraw; /* Flag for SizeWindow() in progress */
  25.  
  26. /* Structures for window menu */
  27. static struct Menu *wmn=NULL;
  28. #define OTMENU_ID   1
  29. #define CDMENU_ID   2
  30. #define ABMENU_ID   3
  31. extern struct EasyStruct AboutES;
  32. #define QUMENU_ID   4
  33. static struct NewMenu mdata[]={
  34.       {NM_TITLE,"TM Dock Menu"  ,NULL,0,~0,NULL},
  35.        {NM_ITEM,"Open TM Window",NULL,0,~0,OTMENU_ID},
  36.        {NM_ITEM,"Close TM Dock" ,"C" ,0,~0,CDMENU_ID},
  37.        {NM_ITEM,NM_BARLABEL     ,NULL,0,~0,NULL},
  38.        {NM_ITEM,"About..."      ,NULL,0,~0,ABMENU_ID},
  39.        {NM_ITEM,NM_BARLABEL     ,NULL,0,~0,NULL},
  40.        {NM_ITEM,"Quit"          ,"Q" ,0,~0,QUMENU_ID},
  41.       {NM_END,NULL,NULL,0,~0,NULL}};
  42.  
  43. /* Structures for dock list */
  44. static struct List DockList;
  45.  
  46. /* Draw all images */
  47. static void DrawDockImages(void)
  48. {
  49.  int x=XOff,y=YOff;
  50.  struct Node *dn=GetHead(&DockList);
  51.  struct Region *reg,*oreg;
  52.  struct Rectangle rect;
  53.  
  54.  /* Get memory for region */
  55.  if (!(reg=NewRegion())) goto die1;
  56.  
  57.  /* Init rectangle */
  58.  if (DockVertical)
  59.   {
  60.    rect.MinX=XOff;
  61.    rect.MaxX=XOff+DockXSize-2;
  62.   }
  63.  else
  64.   {
  65.    rect.MinY=YOff;
  66.    rect.MaxY=YOff+DockYSize-2;
  67.   }
  68.  
  69.  /* Clear Window */
  70.  SetAPen(rp,0);
  71.  SetDrMd(rp,JAM1);
  72.  RectFill(rp,XOff-1,YOff-1,XOff+ww-2,YOff+wh-2);
  73.  
  74.  /* Draw all Docks */
  75.  while (dn)
  76.   {
  77.    /* Create clipping rectangle and add it to our window */
  78.    if (DockVertical)
  79.     {
  80.      rect.MinY=y;
  81.      rect.MaxY=y+DockYSize-2;
  82.     }
  83.    else
  84.     {
  85.      rect.MinX=x;
  86.      rect.MaxX=x+DockXSize-2;
  87.     }
  88.    if (!OrRectRegion(reg,&rect)) goto die2;
  89.    oreg=InstallClipRegion(w->WLayer,reg);
  90.  
  91.    /* Draw Image */
  92.    DrawImage(rp,((struct ToolNode *) dn->ln_Name)->tn_Dock->
  93.                   do_Gadget.GadgetRender,x,y);
  94.  
  95.    /* Remove clipping region */
  96.    InstallClipRegion(w->WLayer,oreg);
  97.    ClearRegion(reg);
  98.  
  99.    /* Calculate next position */
  100.    if (DockVertical)
  101.     y+=DockYSize;
  102.    else
  103.     x+=DockXSize;
  104.  
  105.    /* Next dock */
  106.    dn=GetSucc((struct ToolNode *) dn);
  107.   }
  108.  
  109.  /* Something has gone wrong */
  110. die2: DisposeRegion(reg);
  111. die1: DoDraw=FALSE;       /* Drawing finished */
  112.       return;
  113. }
  114.  
  115. /* Invert a dock image */
  116. void SelectDock(struct ToolNode *tn, WORD dockx, WORD docky, BOOL sel)
  117. {
  118.  WORD x,y;
  119.  struct Gadget *g=&tn->tn_Dock->do_Gadget;
  120.  
  121.  if (DockVertical)
  122.   {
  123.    x=XOff;
  124.    y=(docky-YOff)/DockYSize*DockYSize+YOff;
  125.   }
  126.  else
  127.   {
  128.    x=(dockx-XOff)/DockXSize*DockXSize+XOff;
  129.    y=YOff;
  130.   }
  131.  
  132.  /* Two image icon? */
  133.  if ((g->Flags&GFLG_GADGHIGHBITS)==GFLG_GADGHIMAGE)
  134.   {
  135.    struct Region *reg;
  136.  
  137.    /* Alloc clip region */
  138.    if (reg=NewRegion())
  139.     {
  140.      struct Rectangle rect;
  141.  
  142.      /* Build rectangle */
  143.      rect.MinX=x;
  144.      rect.MaxX=x+DockXSize-2;
  145.      rect.MinY=y;
  146.      rect.MaxY=y+DockYSize-2;
  147.  
  148.      /* Build clip region */
  149.      if (OrRectRegion(reg,&rect))
  150.       {
  151.        struct Region *oreg;
  152.  
  153.        /* Install new clip region */
  154.        oreg=InstallClipRegion(w->WLayer,reg);
  155.  
  156.        /* Clear region */
  157.        SetDrMd(rp,JAM1);
  158.        SetAPen(rp,0);
  159.        RectFill(rp,x,y,rect.MaxX,rect.MaxY);
  160.  
  161.        /* Draw Image */
  162.        DrawImage(rp,sel?g->SelectRender:g->GadgetRender,x,y);
  163.  
  164.        /* Remove clipping region */
  165.        InstallClipRegion(w->WLayer,oreg);
  166.       }
  167.  
  168.      /* Free region */
  169.      DisposeRegion(reg);
  170.     }
  171.   }
  172.  else
  173.   {
  174.    /* One image icon, only complement it. Set draw mode */
  175.    SetDrMd(rp,COMPLEMENT);
  176.    SetAPen(rp,0xff);
  177.    RectFill(rp,x,y,x+DockXSize-2,y+DockYSize-2);
  178.   }
  179. }
  180.  
  181. /* Open dock window */
  182. void OpenDockWindow(void)
  183. {
  184.  struct TextFont *f;
  185.  
  186.  /* Are any docks active or window already open? */
  187.  if (!DockCount || dockwinsig) return; /* No, don't open window */
  188.  
  189.  if (!(pubsc=LockPubScreen(WBScreenName))) /* Lock Workbench screen */
  190.   goto odw1;
  191.  
  192.  /* Get Offsets */
  193.  if (!(f=OpenFont(pubsc->Font))) goto odw2;
  194.  XOff=pubsc->WBorLeft+1;
  195.  YOff=pubsc->WBorTop+f->tf_YSize+2;
  196.  CloseFont(f);
  197.  
  198.  if (!(vi=GetVisualInfo(pubsc,TAG_DONE))) /* Get visual information */
  199.   goto odw2;
  200.  
  201.  /* Create menus */
  202.  if (!(wmn=CreateMenus(mdata,
  203.                        GTMN_FullMenu,TRUE,
  204.                        TAG_DONE))) goto odw3;
  205.  
  206.  /* Layout menus */
  207.  if (!LayoutMenus(wmn,vi,TAG_DONE)) goto odw4;
  208.  
  209.  /* Calculate window size */
  210.  if (DockVertical)
  211.   {
  212.    ww=DockXSize+1;
  213.    wh=DockYSize*DockCount+1;
  214.   }
  215.  else
  216.   {
  217.    ww=DockXSize*DockCount+1;
  218.    wh=DockYSize+1;
  219.   }
  220.  
  221.  /* Open window */
  222.  if (!(w=OpenWindowTags(NULL,WA_Left,DockXPos,
  223.                              WA_Top,DockYPos,
  224.                              WA_InnerWidth,ww,
  225.                              WA_InnerHeight,wh,
  226.                              WA_PubScreen,pubsc,
  227.                              WA_AutoAdjust,TRUE,
  228.                              WA_IDCMP,IDCMP_CLOSEWINDOW|IDCMP_MOUSEBUTTONS|
  229.                                       IDCMP_CHANGEWINDOW|IDCMP_NEWSIZE|
  230.                                       IDCMP_INACTIVEWINDOW|IDCMP_MENUPICK,
  231.                              WA_Flags,WFLG_CLOSEGADGET|WFLG_DRAGBAR|
  232.                                       WFLG_DEPTHGADGET|WFLG_SMART_REFRESH,
  233.                              TAG_DONE)))
  234.   goto odw4;
  235.  if (DockToBack) WindowToBack(w);
  236.  
  237.  /* Add menu to window */
  238.  if (!SetMenuStrip(w,wmn))
  239.   goto odw5;
  240.  
  241.  /* Notify Workbench about window */
  242.  if (!(aw=AddAppWindowA(DOCKWINAPPID,NULL,w,MyMP,NULL)))
  243.   goto odw6;
  244.  
  245.  /* Dock window open */
  246.  UnlockPubScreen(NULL,pubsc);
  247.  rp=w->RPort;
  248.  DrawDockImages();
  249.  wp=w->UserPort;
  250.  dockwinsig=1L<<wp->mp_SigBit;
  251.  globalsigs|=dockwinsig;
  252.  ShowDock=TRUE;
  253.  StatWinDockState(TRUE);
  254.  return;
  255.  
  256.  /* Something has gone wrong... */
  257. odw6: ClearMenuStrip(w);
  258. odw5: CloseWindow(w);
  259. odw4: FreeMenus(wmn);
  260. odw3: FreeVisualInfo(vi);
  261. odw2: UnlockPubScreen(NULL,pubsc);
  262. odw1: return;
  263. }
  264.  
  265. /* Close dock window */
  266. void CloseDockWindow(void)
  267. {
  268.  if (dockwinsig)
  269.   {
  270.    RemoveAppWindow(aw);
  271.    ClearMenuStrip(w);
  272.    CloseWindow(w);
  273.    FreeMenus(wmn);
  274.    FreeVisualInfo(vi);
  275.    globalsigs&=~dockwinsig;
  276.    dockwinsig=0;
  277.    ShowDock=FALSE;
  278.    StatWinDockState(FALSE);
  279.   }
  280. }
  281.  
  282. /* Find dock that correspondences to X,Y position */
  283. struct ToolNode *FindDock(WORD x, WORD y)
  284. {
  285.  struct Node *dn;
  286.  LONG i;
  287.  
  288.  /* Out of bounds? */
  289.  if ((x<XOff) || (y<YOff)) return(NULL);
  290.  
  291.  /* Calculate ordinal number */
  292.  if (DockVertical)
  293.   {
  294.    i=(y-YOff)/DockYSize;
  295.    if (x>=(XOff+DockXSize)) return(NULL);
  296.   }
  297.  else
  298.   {
  299.    i=(x-XOff)/DockXSize;
  300.    if (y>=(YOff+DockYSize)) return(NULL);
  301.   }
  302.  
  303.  /* Out of bounds? */
  304.  if (i<0) return(NULL);
  305.  
  306.  /* Search tool */
  307.  dn=GetHead(&DockList);
  308.  while (i && dn)
  309.   {
  310.    /* Next Dock */
  311.    dn=GetSucc((struct ToolNode *) dn);
  312.    i--;
  313.   }
  314.  
  315.  /* Retreive ToolNode */
  316.  if (dn)
  317.   return(dn->ln_Name);
  318.  else
  319.   return(NULL);
  320. }
  321.  
  322. /* Handle window events */
  323. void HandleDockWinEvent(void)
  324. {
  325.  static struct ToolNode *otn=NULL;
  326.  static WORD ox,oy;
  327.  BOOL clwin=FALSE;
  328.  struct IntuiMessage *msg;
  329.  
  330.  while (msg=GetMsg(wp))        /* Get Intuition messages */
  331.   {
  332.    switch (msg->Class)
  333.     {
  334.      case IDCMP_CLOSEWINDOW:   /* User selected the close window gadget */
  335.       clwin=TRUE;
  336.       break;
  337.      case IDCMP_MOUSEBUTTONS:  /* User pressed mouse buttons */
  338.       switch(msg->Code)
  339.        {
  340.         case SELECTDOWN:       /* User pressed select button */
  341.          /* Save selected tool */
  342.          ox=msg->MouseX;       /* Save coordinates */
  343.          oy=msg->MouseY;
  344.          if (otn=FindDock(ox,oy))     /* Find selected tool */
  345.           SelectDock(otn,ox,oy,TRUE); /* If tool found, invert its image */
  346.          break;
  347.         case SELECTUP:         /* User released select button */
  348.          struct ToolNode *tn;
  349.  
  350.          /* Save selected tool */
  351.          tn=FindDock(msg->MouseX,msg->MouseY);
  352.  
  353.          /* Tool selected and same tool as button pressed? */
  354.          if (tn && (otn==tn))
  355.           StartTool(tn,NULL);  /* Yes, start tool with no args */
  356.  
  357.          /* Invert DockImage */
  358.          if (otn)
  359.           {
  360.            SelectDock(otn,ox,oy,FALSE);
  361.            otn=NULL;           /* invalidate pointer */
  362.           }
  363.        }
  364.       break;
  365.      case IDCMP_INACTIVEWINDOW: /* Window has gone inactive */
  366.       /* Missed a SELECTUP???? */
  367.       if (otn)
  368.        {
  369.         SelectDock(otn,ox,oy,FALSE); /* Yes. Invert dock again */
  370.         otn=NULL;                     /* invalidate pointer */
  371.        }
  372.       break;
  373.      case IDCMP_CHANGEWINDOW:   /* User has moved the window */
  374.       DockXPos=w->LeftEdge;     /* Update window coordinates */
  375.       DockYPos=w->TopEdge;
  376.       break;
  377.      case IDCMP_NEWSIZE:        /* Window has new size */
  378.       /* Was a SizeWindow() in progress? Yes, it is completed now. */
  379.       /* We can now draw the images safely. */
  380.       if (DoDraw) DrawDockImages();
  381.       break;
  382.      case IDCMP_MENUPICK:       /* User selected a menu */
  383.       USHORT mnum=msg->Code;
  384.  
  385.       while (mnum!=MENUNULL)    /* Scan all menu events */
  386.        {
  387.         struct MenuItem *mi=ItemAddress(wmn,mnum);
  388.  
  389.         switch(GTMENUITEM_USERDATA(mi))
  390.          {
  391.           case OTMENU_ID:         /* User selected open TM window menu item */
  392.            OpenStatusWindow(TRUE);
  393.            break;
  394.           case CDMENU_ID:         /* User selected close TM dock menu item */
  395.            clwin=TRUE;
  396.            break;
  397.           case ABMENU_ID:         /* User selected about menu item */
  398.            EasyRequest(w,&AboutES,NULL,"");
  399.            break;
  400.           case QUMENU_ID:         /* User selected quit menu item */
  401.            if (!clwin)
  402.             {
  403.              SetQuitFlag();
  404.              if (!running) clwin=TRUE;
  405.             }
  406.            break;
  407.          }
  408.  
  409.         /* Next selected menu */
  410.         mnum=mi->NextSelect;
  411.        }
  412.       break;
  413.     }
  414.    ReplyMsg((struct Message *) msg); /* Reply message */
  415.   }
  416.  
  417.  if (clwin)
  418.   {
  419.    otn=NULL;
  420.    CloseDockWindow();
  421.   }
  422. }
  423.  
  424. /* Redraw dock window */
  425. static void RefreshDockWindow(BOOL added)
  426. {
  427.  /* Not in initialization  phase? */
  428.  if (ShowDock)
  429.   /* Dock window open? */
  430.   if (dockwinsig)
  431.    /* Yes, change window contents */
  432.    if (DockCount)
  433.     { /* Dock added? */
  434.      if (added)
  435.       if (DockVertical)     /* Yes, enlarge window */
  436.        {
  437.         SizeWindow(w,0,DockYSize);
  438.         wh+=DockYSize;
  439.        }
  440.       else
  441.        {
  442.         SizeWindow(w,DockXSize,0);
  443.         ww+=DockXSize;
  444.        }
  445.      else
  446.       if (DockVertical)     /* No, reduce window size */
  447.        {
  448.         SizeWindow(w,0,-DockYSize);
  449.         wh-=DockYSize;
  450.        }
  451.       else
  452.        {
  453.         SizeWindow(w,-DockXSize,0);
  454.         ww-=DockXSize;
  455.        }
  456.  
  457.      /* SizeWindow() in progress */
  458.      DoDraw=TRUE;
  459.     }
  460.    else CloseDockWindow(); /* No dock to show, so close the window */
  461.   else if (added) OpenDockWindow(); /* No, open window */
  462. }
  463.  
  464. /* Add a dock to the list */
  465. BOOL AddDock(struct ToolNode *tn)
  466. {
  467.  struct Node *dn;
  468.  
  469.  /* Get memory for new dock node */
  470.  if (!(dn=malloc(sizeof(struct Node)))) return(FALSE);
  471.  
  472.  /* Initialize dock list */
  473.  if (DockCount==0) NewList(&DockList);
  474.  
  475.  /* Append dock node at the of list */
  476.  dn->ln_Name=tn;
  477.  AddTail(&DockList,dn);
  478.  DockCount++;
  479.  
  480.  /* Refresh dock window */
  481.  RefreshDockWindow(TRUE);
  482.  
  483.  return(TRUE);
  484. }
  485.  
  486. /* Remove a dock from the list */
  487. void RemDock(struct ToolNode *tn)
  488. {
  489.  struct Node *dn;
  490.  
  491.  /* Search node in dock list */
  492.  dn=GetHead(&DockList);
  493.  while (dn)
  494.   {
  495.    /* Node found? Yes --> Leave loop */
  496.    if ((struct ToolNode *) dn->ln_Name==tn) break;
  497.  
  498.    /* Next node */
  499.    dn=GetSucc((struct ToolNode *) dn);
  500.   }
  501.  
  502.  /* Remove node */
  503.  Remove(dn);
  504.  DockCount--;
  505.  
  506.  /* Refresh dock window */
  507.  RefreshDockWindow(FALSE);
  508. }
  509.